// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: donggu

#pragma once

// std
#include <map>
#include <memory>
#include <regex>
#include <string>
#include <vector>

// internal
#include "coin2/base/log.h"
#include "coin2/exchange/base/feed_util/liquidation_order.h"
#include "coin2/exchange/base/feed/processor.h"
#include "coin2/exchange/base/symbology/product_info.h"
#include "coin2/exchange/base/market/enums.h"
#include "coin2/exchange/bitmex/feed_v1/update.h"
#include "coin2/exchange/base/symbology/product_holder_manager.h"

namespace coin2::exchange::bitmex::feed_v1 {
namespace impl {
using namespace std::string_literals;
using coin2::exchange::base::market::ExchangeType;
using coin2::exchange::base::market::MarketType;
using coin2::exchange::base::symbology::IProduct;
using coin2::exchange::base::symbology::IProductHolder;
using coin2::exchange::base::feed::IFeedSubscriber;
using coin2::exchange::base::symbology::ProductHolderManager;

class BitmexFeedProcessor : public coin2::exchange::base::feed::FeedParsingProcessor {
 public:
  explicit BitmexFeedProcessor(
      const std::string& system_name,
      const coin2::exchange::di::ConstantInjection& ci,
      const feed::RawParserConfig& config)
      : FeedParsingProcessor(
            system_name,
            MarketExchangeApi{MarketType::Futures, ExchangeType::Bitmex, "v1"},
            ci,
            config,
            "cc/coin2/exchange/bitmex/feed_v1/schema.json"),
        publish_bbo_book_only_(config.publish_bbo_book_only()) {
      product_holder_manager_ = std::make_unique<ProductHolderManager>(coin::proto::ProductHolderManagerConfig());
  }

  void OnTopicRecord(const base::executor::TopicRecordPacket& packet) override;
  void AddProduct(const IProduct& product, IFeedSubscriber* subscriber) override;

 protected:
  const bool publish_bbo_book_only_;

 private:
  BitmexFeedUpdateParser parser_;
  std::unordered_map<std::string, std::unique_ptr<IProductHolder>> native_to_pi_;
  std::unordered_map<std::string, LiquidationOrder> native_to_liquidation_order_;
  std::unique_ptr<ProductHolderManager> product_holder_manager_;
};
}  // namespace impl
using impl::BitmexFeedProcessor;
}  // namespace coin2::exchange::bitmex::feed_v1
